/**
 * 灭火器诊断点
*/
#include "exth_diage_node.h"
#include "stdio.h"
#include "diagnostic.h"
#include "MidDio.h"
#include "MidAdc.h"
#include "exth.h"

#include "event_queue_Handle.h"


#define VALVE_OUTPUT_VALVE		22000  //mv



//事件节点
STR_DIAG_CFG_NODE stDiagPump1SelfCheckCfg;
STR_DIAG_CFG_NODE stDiagPump2SelfCheckCfg ;
STR_DIAG_CFG_NODE stDiagPierceFaultCfg ;
STR_DIAG_CFG_NODE stDiagBallFaultCfg ;
STR_DIAG_CFG_NODE stDiagPump1OpenCfg ;
STR_DIAG_CFG_NODE stDiagPump2OpenCfg ;



/**
 * 泵自检诊断函数
 * 返回1 = 有故障， 0 = 无故障 
 * 函数进入后判断泵启动的诊断开关是否置位。没有置位就不进行诊断。
 * 启动泵后，调用泵自检开始函数，打开泵自检开关，？
 * 然后 可以执行泵自检函数内容， 
 * 失败时间设为5秒（5000ms）,
 * 通过时间设为100ms,检测周期100ms,
 * 相当于，一直泵自检开始时，
 * 采集不到反馈信号，就返回有故障，如果持续5秒没有采集到反馈信号，
 * 就认为检测失败，如果期间有采集到一次反馈信号，就认为检测通过。
 * 进行检测确认时，如果未采集到反馈信号，抛出泵自检故障事件，
 * 设置灭火器泵状态为 诊断失败
*/
uint32_t  exthPump1Diag()
{	
//    DEBUG_LOG_INFO(DEBUG_LEVEL_2, " -----------------------------PumpSelf  DIAG \n");
    bool feedbackSignal = DioReadChannel(PUMP1_FEEDBACK);  
	
	//	//TEST
	//	feedbackSignal = 1;
	
    if(feedbackSignal == TRUE)
    {      
        return 0;
    }
    else
	{
		return 1;
	}      
}


/**
 * 按下 自检按键后，泵自检诊断确认函数
 * 进行检测确认时，如果未采集到反馈信号，
 * 诊断失败，抛出泵自检故障事件 
 * 将该诊断节点删除，不再进行泵自检诊断。
*/
void exthPump1SelfcheckConfirm(bool  confirmed)
{
     if(confirmed ==1)
	{  //诊断未通过
		EvtFaultWrite(FAULT_PUMP_SELFCHECK);
		//DEBUG_LOG_INFO(DEBUG_LEVEL_2, "================PumpSelf111  DIAG FAIL  \n");      
    }
    else
	{
		//DEBUG_LOG_INFO(DEBUG_LEVEL_2, "================PumpSelf111  DIAG PASS  \n");        
    }
	
	DioWriteChannel(PUMP1_OPEN, 0);			// 诊断结束，关闭泵
	DiagDltNode(&stDiagPump1SelfCheckCfg);
}


/**
 * 灭火器启动时，泵启动的诊断确认函数
 * 进行检测确认时，如果未采集到反馈信号，
 * 诊断失败，抛出泵自检故障事件，设置该灭火器设备泵状态为 
 * 诊断失败（灭火器设备文件中提供一个设置灭火器泵诊断状态的函数）。
 * 采集到反馈信号，设置灭火器泵状态为 诊断通过进行确认后，
 * 将该诊断节点删除，不再进行泵自检诊断。
*/
void exthPump1OpenConfirm(bool  confirmed)
{
     if(confirmed ==1)
	{  //诊断未通过
		ExthSetPumpDiagFeedback(EXTH_1, EXTH_PUMP_1, DIAG_FAIL);
		 DEBUG_LOG_INFO(DEBUG_LEVEL_2, "================Pump Open111  DIAG FAIL  \n");      
    }
    else
	{
		ExthSetPumpDiagFeedback(EXTH_1, EXTH_PUMP_1, DIAG_PASS);
		DEBUG_LOG_INFO(DEBUG_LEVEL_2, "================Pump  Open1111  DIAG PASS  \n");
        
    }
	
	DiagDltNode(&stDiagPump1OpenCfg);
	
}



/**
 * 泵自检诊断函数
 * 返回1 = 有故障， 0 = 无故障 
 * 函数进入后判断泵启动的诊断开关是否置位。没有置位就不进行诊断。
 * 启动泵后，调用泵自检开始函数，打开泵自检开关，？
 * 然后 可以执行泵自检函数内容， 
 * 失败时间设为5秒（5000ms）,
 * 通过时间设为100ms,检测周期100ms,
 * 相当于，一直泵自检开始时，
 * 采集不到反馈信号，就返回有故障，如果持续5秒没有采集到反馈信号，
 * 就认为检测失败，如果期间有采集到一次反馈信号，就认为检测通过。
 * 进行检测确认时，如果未采集到反馈信号，抛出泵自检故障事件，
 * 设置灭火器泵状态为 诊断失败
*/
uint32_t  exthPump2Diag()
{	
//    DEBUG_LOG_INFO(DEBUG_LEVEL_2, " -----------------------------PumpSelf  DIAG \n");
    
	bool feedbackSignal = DioReadChannel(PUMP2_FEEDBACK);  
	
	//	//TEST
	//	feedbackSignal = 1;
	
	
    if(feedbackSignal == TRUE)
    {      
        return 0;
    }
    else
	{
		return 1;
	}
        
}


/**
 * 泵自检诊断确认函数
 * 进行检测确认时，如果未采集到反馈信号，
 * 诊断失败，抛出泵自检故障事件，设置该灭火器设备泵状态为 
 * 诊断失败（灭火器设备文件中提供一个设置灭火器泵诊断状态的函数）。
 * 采集到反馈信号，设置灭火器泵状态为 诊断通过进行确认后，
 * 将诊断开关关闭，不再进行泵自检诊断。
*/
void exthPump2SelfcheckConfirm(bool  confirmed)
{
     if(confirmed ==1) //诊断未通过
	{ 
		EvtFaultWrite(FAULT_PUMP_SELFCHECK);
		// DEBUG_LOG_INFO(DEBUG_LEVEL_2, "================PumpSelf22  DIAG FAIL  \n");      
    }
    else
	{
		// DEBUG_LOG_INFO(DEBUG_LEVEL_2, "================PumpSelf222  DIAG PASS  \n");
        
    }
	DioWriteChannel(PUMP1_OPEN, 0);			// 诊断结束，关闭泵
	DiagDltNode(&stDiagPump2SelfCheckCfg);
	
}


void exthPump2OpenConfirm(bool  confirmed)
{
     if(confirmed ==1) //诊断未通过
	{ 	
		ExthSetPumpDiagFeedback(EXTH_1, EXTH_PUMP_2, DIAG_FAIL);

//		DEBUG_LOG_INFO(DEBUG_LEVEL_2, "================PumpSelf22  DIAG FAIL  \n");      
    }
    else
	{
		ExthSetPumpDiagFeedback(EXTH_1, EXTH_PUMP_2, DIAG_PASS);

//		DEBUG_LOG_INFO(DEBUG_LEVEL_2, "================PumpSelf222  DIAG PASS  \n");
        
    }
	DiagDltNode(&stDiagPump2OpenCfg);
	
}

/**
 * 刺破阀启动，诊断函数
 * 返回1 = 有故障， 0 = 无故障 
 * 设有诊断开关，当刺破阀启动时，调用诊断开关打开，
 * 开始执行内部诊断逻辑。判断后级是否有电压输出，
 * 有输出认为是启动成功。没有输出认为是启动失败。检测间隔100ms，
 * 检测失败持续时间2秒，检测成功持续时间 100ms
*/
uint32_t exthPierceValueDiag( void)
{        
    UINT16 buf = AdcDmaValu(SAMPLE_PIERCE_VALVE); //  TRUE 有电压  FALSE 无电压、
	
//	DEBUG_LOG_INFO(DEBUG_LEVEL_2, " PierceValue  DIAG \n");

	//	//test
	//	buf = 23000;
	
    if(buf  > VALVE_OUTPUT_VALVE)
	{
        printf("启动成功");
        return 0;
    }
    else 
	{
		return 1;
	}
}


/**
 * 刺破阀启动 诊断确认函数
 * 参数confirmed: 确认状态，1=诊断未通过失败  、
 *                         0 = 诊断通过 成功
 * 当 诊断通过时，将灭火器的主阀（刺破阀）状态设置为 诊断成功。
 * 当 诊断失败时，将灭火器的主阀（刺破阀）状态设置为 诊断失败，
 * 同时抛出刺破阀启动故障事件。
 * 诊断确认函数执行后，将诊断开关关闭，不再进行诊断。
*/
void  exthPierceValueConfirm(bool  confirmed){

    if(confirmed ==1)
	{  //诊断未通过
		/* 设置灭火器的 刺破阀反馈状态  FAIL */
		ExthSetMainValveDiagFeedback(EXTH_1, PIERCE_VALVE, DIAG_FAIL);
//		DEBUG_LOG_INFO(DEBUG_LEVEL_2, "================PierceValue  DIAG FAIL  \n");      
    }
    else
	{
		/* 设置灭火器的 刺破阀反馈状态 PASS*/
		ExthSetMainValveDiagFeedback(EXTH_1, PIERCE_VALVE, DIAG_PASS);
//        DEBUG_LOG_INFO(DEBUG_LEVEL_2, "================PierceValue  DIAG PASS  \n");
        
    }
	DiagDltNode(&stDiagPierceFaultCfg);
}



/**
 * 球阀启动 诊断开始函数
 * 1 = 有故障， 0 = 无故障
 * 设有诊断开关，当球阀启动时，调用诊断开关打开，
 * 开始执行内部诊断逻辑。判断后级是否有电压输出，
 * 有输出认为是启动成功。没有输出认为是启动失败。
 * 检测间隔100ms，检测失败持续时间2秒，
 * 检测成功持续时间 100ms
*/
uint32_t exthBallValueDiag( void)
{      	
    UINT16 buf = AdcDmaValu(SAMPLE_BALL_VALVE); //假的 过去后级是否有电压  TRUE 有电压  FALSE 无电压
	
	DEBUG_LOG_INFO(DEBUG_LEVEL_2, " BallValue DIAG \n");

	//	//TEST
	//	buf = 23000;
	
    if(buf  > VALVE_OUTPUT_VALVE)
	{
//		DEBUG_LOG_INFO(DEBUG_LEVEL_2, " BallValue DIAG  diag sucess \n");

        printf("启动成功");
        return 0;
    }
    else 
        return 1;
}

/**
 * 球阀启动 诊断确认函数
 * 参数confirmed: 确认状态，1=诊断未通过失败  、 0 = 诊断通过 成功
 * 当 诊断通过时，将灭火器的球阀状态设置为 诊断成功。
 * 当 诊断失败时，将灭火器的球阀状态设置为 诊断失败，
 * 同时抛出球阀启动故障事件。
 * 诊断确认函数执行后，将诊断开关关闭，不再进行诊断。
*/
void exthBallValueConfirm(bool  confirmed)
{
	if(confirmed ==1)
	{  //诊断未通过
		/* 设置灭火器的 刺破阀反馈状态为诊断失败 */
		ExthSetMainValveDiagFeedback(EXTH_1, BALL_VALVE, DIAG_FAIL);

         DEBUG_LOG_INFO(DEBUG_LEVEL_2, "================BallValue  DIAG FAIL  \n");      
    }
    else
	{		
		//* 设置灭火器的 刺破阀反馈状态为诊断通过*/
		ExthSetMainValveDiagFeedback(EXTH_1, BALL_VALVE, DIAG_PASS);
        DEBUG_LOG_INFO(DEBUG_LEVEL_2, "================BallValue DIAG PASS  \n");
        
    }
	
	DiagDltNode(&stDiagBallFaultCfg);
}




/**
 * 刺破阀阀异常 诊断函数
 * 1 = 有故障， 0 = 无故障
 * 持续检测，检测刺破阀所连接的HSD电路中的启动电流检测，
 * 正常情况下，采集电压近乎于0，
 * 如果采集电压持续两秒高于0.5V， 就认为 诊断不通过。 
*/
uint32_t exthPierceAbnormalDiag( void)
{
    uint8_t buf  = AdcDmaValu(SAMPLE_PIERCE_VALVE_ELEC); // 采集 正常情况下的 刺破阀电流
	
	//DEBUG_LOG_INFO(DEBUG_LEVEL_2, " PierceAbnorma \n");	
    if (buf > 0.5) 
	{
        printf("诊断不通过");
        return 1;
	}
    else
	{
        printf("诊断成功");
        return 0;
    }

}

/**
 *刺破阀异常 诊断确认函数
 confirmed: 确认状态，1=诊断未通过失败  、 0 = 诊断通过 成功
 当 诊断失败时，抛出球阀异常故障事件。
*/
void exthPierceAbnormalConfirm(bool  confirmed)
{
	DEBUG_LOG_INFO(DEBUG_LEVEL_2, " PierceAbnormal  diag conmfirm \n");

    if(confirmed == 1)
	{
       EvtFaultWrite(FAULT_PIERCEVAL_ABNORM);
        printf("诊断未通过");
		//DEBUG_LOG_INFO(DEBUG_LEVEL_2, " ===================PierceAbnormal  diag conmfirm fail \n");
        return ;
    }
    else
	{
        printf("诊断通过");
		//DEBUG_LOG_INFO(DEBUG_LEVEL_2, " ==========================PierceAbnormal  diag conmfirm pass \n");
        return ;
    }
}

/**
 * 球阀异常 诊断函数
 * 1 = 有故障， 0 = 无故障 
 * 持续检测，检测刺破阀所连接的HSD电路中的启动电流检测，
 * 正常情况下，采集电压近乎于0，
 * 如果采集电压持续两秒高于0.5V， 就认为 诊断不通过。
 * 
*/
uint32_t exthBallValueAbnormalDiag(void)
{
    uint8_t buf ;

    buf = AdcDmaValu(SAMPLE_BALL_VALVE_ELEC); // 假的模拟获取电压采集值
	
	//DEBUG_LOG_INFO(DEBUG_LEVEL_2, " BallValueAbnorma DIAG \n");
    
	if (buf > 0.5) 
	{
        printf("诊断不通过");
		
        return 1;
    } 
    else
	{
        printf("诊断成功");		
        return 0;
    }
}




/**
 * 球阀异常 诊断确认函数
 * confirmed: 确认状态，1=诊断未通过失败  、 0 = 诊断通过 成功
 * 当 诊断失败时，抛出刺破阀异常故障事件。
*/
void exthBallValueAbnormalConfirm(bool  confirmed)
{
    if(confirmed == 1)
	{      
		EvtFaultWrite(FAULT_BALLVAL_ABNORM);
        printf("诊断未通过\n");
		//DEBUG_LOG_INFO(DEBUG_LEVEL_2, " BallValueAbnormal  diag conmfirm fail \n");
    }
	else
	{
		//DEBUG_LOG_INFO(DEBUG_LEVEL_2, " BallValueAbnormal  diag conmfirm pass \n");
	
	//		// test
	//		ExthRequest(EXTH_1, 1, NULL);
	}
    
}



//事件节点

/* 泵1自检 诊断节点*/
STR_DIAG_CFG_NODE stDiagPump1SelfCheckCfg =
{                   
    .stDTCStatus = 0,
    .usPeriod = EXTH_PUMP_FAULT_PERIOD,                  //周期
    .usPassLimit = EXTH_PUMP_FAULT_PASS_LIMIT,               //通过次数
    .usFailedLimit = EXTH_PUMP_FAULT_FAILED_LIMIT,             //失败次数
    .sCounter = 0,                                      //故障计数器
    .irfDiagFunction = exthPump1Diag,           //故障诊断函数
    .irfFaultConfirm = exthPump1SelfcheckConfirm,       //故障确认函数
};

/* 泵2自检 诊断节点*/
STR_DIAG_CFG_NODE stDiagPump2SelfCheckCfg =
{                   //泵
    .stDTCStatus = 0,
    .usPeriod = EXTH_PUMP_FAULT_PERIOD,                  //周期
    .usPassLimit = EXTH_PUMP_FAULT_PASS_LIMIT,               //通过次数
    .usFailedLimit = EXTH_PUMP_FAULT_FAILED_LIMIT,             //失败次数
    .sCounter = 0,                                      //故障计数器
    .irfDiagFunction = exthPump2Diag,           //故障诊断函数
    .irfFaultConfirm = exthPump2SelfcheckConfirm,       //故障确认函数
};



/* 灭火器启动 泵1启动 诊断节点*/

STR_DIAG_CFG_NODE stDiagPump1OpenCfg =
{                   
    .stDTCStatus = 0,
    .usPeriod = EXTH_PUMP_FAULT_PERIOD,                  //周期
    .usPassLimit = EXTH_PUMP_FAULT_PASS_LIMIT,               //通过次数
    .usFailedLimit = EXTH_PUMP_FAULT_FAILED_LIMIT,             //失败次数
    .sCounter = 0,                                      //故障计数器
    .irfDiagFunction = exthPump1Diag,           //故障诊断函数
    .irfFaultConfirm = exthPump1OpenConfirm,       //故障确认函数
};

/* 灭火器启动 泵2启动 诊断节点*/
STR_DIAG_CFG_NODE stDiagPump2OpenCfg =
{                   //泵
    .stDTCStatus = 0,
    .usPeriod = EXTH_PUMP_FAULT_PERIOD,                  //周期
    .usPassLimit = EXTH_PUMP_FAULT_PASS_LIMIT,               //通过次数
    .usFailedLimit = EXTH_PUMP_FAULT_FAILED_LIMIT,             //失败次数
    .sCounter = 0,                                      //故障计数器
    .irfDiagFunction = exthPump2Diag,           //故障诊断函数
    .irfFaultConfirm = exthPump2OpenConfirm,       //故障确认函数
};

/* 灭火器启动  刺破阀启动 诊断节点*/
STR_DIAG_CFG_NODE stDiagPierceFaultCfg =
{                  
    .stDTCStatus = 0,
    .usPeriod = EXTH_MAIN_FAULT_PERIOD,                      //周期
    .usPassLimit = EXTH_MAIN_FAULT_PASS_LIMIT,               //通过次数
    .usFailedLimit = EXTH_MAIN_FAULT_FAILED_LIMIT,           //失败次数
    .sCounter = 0,                                          //故障计数器
    .irfDiagFunction = exthPierceValueDiag,                    //故障诊断函数
    .irfFaultConfirm = exthPierceValueConfirm,                //故障确认函数
};


/* 灭火器启动  球阀启动 诊断节点*/
STR_DIAG_CFG_NODE stDiagBallFaultCfg =
{
    .stDTCStatus = 0,
    .usPeriod = EXTH_BALL_FAULT_PERIOD,                     //周期
    .usPassLimit = EXTH_BALL_FAULT_PASS_LIMIT,               //通过次数
    .usFailedLimit = EXTH_BALL_FAULT_FAILED_LIMIT,             //失败次数
    .sCounter = 0,                                         //故障计数器
    .irfDiagFunction = exthBallValueDiag,                   //故障诊断函数
    .irfFaultConfirm = exthBallValueConfirm,                //故障确认函数
};


/* 正常检测 刺破阀异常 诊断节点*/
STR_DIAG_CFG_NODE stDiagPierceAbnormalFaultCfg =
{
    .stDTCStatus = 0,
    .usPeriod = EXTH_MAIN_ABNORMAL_FAULT_PERIOD,                     //周期
    .usPassLimit = EXTH_MAIN_ABNORMAL_FAULT_PASS_LIMIT,               //通过次数
    .usFailedLimit = EXTH_MAIN_ABNORMAL_FAULT_FAILED_LIMIT,             //失败次数
    .sCounter = 0,                                         //故障计数器
    .irfDiagFunction = exthPierceAbnormalDiag,                   //故障诊断函数
    .irfFaultConfirm = exthPierceAbnormalConfirm,                //故障确认函数
};


/* 正常检测 球阀异常 诊断节点*/
STR_DIAG_CFG_NODE stDiagBallAbnormalFaultCfg =
{                   
    .stDTCStatus = 0,
    .usPeriod = EXTH_BALL_ABNORMAL_FUALT_PERIOD,                     //周期
    .usPassLimit = EXTH_BALL_ABNORMAL_FAULT_PASS_LIMIT,               //通过次数
    .usFailedLimit = EXTH_BALL_ABNORMAL_FAULT_FAILED_LIMIT,             //失败次数
    .sCounter = 0,                                         //故障计数器
    .irfDiagFunction = exthBallValueAbnormalDiag,                   //故障诊断函数
    .irfFaultConfirm = exthBallValueAbnormalConfirm,                //故障确认函数
};


/**
 * 灭火器诊断初始化
 * 
*/
void diagNormalExthNodeInit(void)
{   		
    DiagAddNode(&stDiagPierceAbnormalFaultCfg);	
    DiagAddNode(&stDiagBallAbnormalFaultCfg);
}


//自检按键 启动泵自检
void DiagPumpSelfcheckStart()
{
	DiagAddNode(&stDiagPump1SelfCheckCfg);
	DiagAddNode(&stDiagPump2SelfCheckCfg);

}



//灭火器启动时，泵启动诊断
void DiagPumpsStart()
{
	DiagAddNode(&stDiagPump1OpenCfg);
	DiagAddNode(&stDiagPump2OpenCfg);

}


// 灭火器启动时，刺破阀启动自检
void DiagPierceValStart()
{
	DiagAddNode(&stDiagPierceFaultCfg);
}

// 灭火器启动时，球阀启动自检
void DiagBallValStart()
{
	DiagAddNode(&stDiagBallFaultCfg);
}



